/**
 * Created by chenwen on 17-5-15.
 */
let https = require("https"),
    crypto = require("crypto"),
    util = require("./util");


const place_method = "";
const version = "1.0";
const product_code = "QUICK_MSECURITY_PAY";

class Alipay {

    /**
     * 构造方法
     * @param appid 应用ID
     * @param privateKey 私有秘钥
     * @param publicKey 共有秘钥
     * @seller_id  商家账号
     */
    constructor(appid, privateKey, publicKey, seller_id,sign_type="RSA2"){
        this.app_id = appid;
        this.privateKey = privateKey;
        this.publicKey = publicKey;
        this.seller_id = seller_id;
        this.sign_type = sign_type;
    }

    /**
     * 生成账单
     * @param body
     */
    fetchPlaceOrder({body="",subject="",out_trade_no,total_amount=0, charset="utf-8",notify_url=""}){
        let placeOrderObj = {
            seller_id : this.seller_id,
            app_id: this.app_id,
            method : place_method,
            charset : charset,
            sign_type : this.sign_type,
//            timestamp : util.formatTime(new Date()),
            timestamp : "2017-05-16 14:06:08",
            version : version,
            notify_url : notify_url,
            biz_content :JSON.stringify({
                body,
                subject,
                out_trade_no,
                total_amount,
                product_code : product_code
            })
        };
        var urlStr = this.createLinkstring(placeOrderObj);
        let sign = this.createSign(placeOrderObj);
        console.log("获得sign:");
        console.log(sign);
        urlStr += "&sign=" + sign;
        urlStr = new Buffer(urlStr,"utf8").toString();
        //这里还没有进行utf-8编码

        return urlStr;
    }
    /**
     * 验证签名
     * @param msg
     */
    verify(msg,sign){
        if(!sign) sign = msg.sign;
        var signStr = this.generateSignValue(msg, true);
        var verify = crypto.createVerify(this.sign_type== "RSA2" ? "SHA256":this.sign_type);
        signStr = new Buffer(signStr);
        verify.update(signStr);
        return verify.verify(this.publicKey, sign, 'base64');
    }

    //把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串
    createLinkstring(para){
        var str = "";
        for(let [key, value] of Object.entries(para)){
            str += key + "=" + value +"&";
        }
        return str.substring(0, str.length-1);
    }

    /**
     * 创建支付宝签名
     * @param obj
     * @returns {*}
     */
    createSign(obj){
        let msg = this.generateSignValue(obj);
        console.log("待签名内容:");
        console.log(msg);
        let sign = crypto.createSign(this.sign_type== "RSA2" ? "SHA256":this.sign_type);
        sign.update(msg);
        return sign.sign(this.privateKey, 'base64');
    }

    generateSignValue(msg, filter_sign_type){
        msg = this.paraFilter(msg, filter_sign_type);
//        console.log("过滤参数");
//        console.log(msg);
        msg = this.argSort(msg);
        return this.createLinkstring(msg);
    }

    /**
     * 除去对象中的空值和签名参数
     * @param para 签名参对象
     * return 去掉空值与签名参数后的新签名参对象
     */
    paraFilter(para, sign_type){
        var para_filter = new Object();
        for (var key in para){
            var falg = key == 'sign' || para[key] == '';
            if(sign_type) falg = falg || key == 'sign_type';
            if(falg){
                continue;
            }
            para_filter[key] = para[key];
        }

        return para_filter;
    }

    /**
     * 对对象排序
     * @param para 排序前的对象
     * return 排序后的对象
     */
    argSort(para){
        var result = new Object();
        var keys = Object.keys(para).sort();
        for (var i = 0; i < keys.length; i++){
            var k = keys[i];
            result[k] = para[k];
        }
        return result;
    }
}

module.exports = Alipay;
